﻿
using Microsoft.EntityFrameworkCore;
using PKISharp.SimplePKI;
using ProxyServer.Acme;
using ProxyServer.Certs;
using ProxyServer.EntityFrameworkCore;
using ProxyServer.Kestrel;
using ProxyServer.Quartz.Jobs;
using Quartz;
using System.Security.Cryptography.X509Certificates;

namespace ProxyServer.HostedService
{
    public class ServerLoader : BackgroundService
    {
        private readonly IServiceScopeFactory _scopeFactory;
        private readonly ILogger<ServerLoader> _logger;

        public ServerLoader(IServiceScopeFactory serviceScopeFactory, ILogger<ServerLoader> logger)
        {
            _scopeFactory = serviceScopeFactory;
            _logger = logger;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            // await CheckForAccount(stoppingToken);

            await LoadCertificates(stoppingToken);
        }

        private async Task LoadCertificates(CancellationToken stoppingToken)
        {
            try
            {
                using (var scope = _scopeFactory.CreateAsyncScope())
                {
                    var selector = scope.ServiceProvider.GetRequiredService<CertificateSelector>();
                    var certMgr = scope.ServiceProvider.GetRequiredService<CertificateManager>();

                    await foreach (var cert in certMgr.GetCertificatesAsync())
                    {
                        selector.Add(cert);
                    }

                    var dev = scope.ServiceProvider.GetRequiredService<DeveloperCertLoader>();

                    var devCerts = await dev.GetCertificatesAsync(stoppingToken);

                    foreach (var devCert in devCerts)
                    {
                        selector.Add(devCert);
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to load certificate");
            }
        }

        private async Task CheckForAccount(CancellationToken stoppingToken)
        {
            using var scope = _scopeFactory.CreateAsyncScope();

            try
            {
                IAcmeState state = scope.ServiceProvider.GetRequiredService<CheckForAcmeAccountState>();
                while (!stoppingToken.IsCancellationRequested)
                {
                    state = await state.MoveNextAsync(stoppingToken);
                }
            }
            catch (OperationCanceledException)
            {
                _logger.LogInformation("ServerLoader exiting...");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "ServerLoader encountered unhandled error");
            }
        }
    }
}
